package com.gwtjs.icustom.configuration;

import static com.gwtjs.icustom.utils.SystemVersionUtil.getOSName;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import cn.hutool.db.Entity;
import cn.hutool.db.handler.EntityListHandler;
import cn.hutool.db.sql.SqlExecutor;

/**
 * <h2>创建sqlite数据库与表</h2>
 */
@Component
public class DbInitConfiguration {

	@Resource
	DataSource dataSource;

	private final static Logger logger = LoggerFactory.getLogger(DbInitConfiguration.class);

	@Value("${spring.datasource.url}")
	private String sqliteDbPath;
	

	/**
	 * <h2>项目启动时初始化</h2>
	 * <p>
	 * linux系统为生产环境,会使用shell脚本直接创建脚本，只有开发环境需要java创建库文件。
	 * </p>
	 * <ul>
	 *  <ol>
	 *  <li>检查数据库文件是否存在,sqlite数据库是文件形式，如果不存在，建立空文件即可</li>
	 *  <li>检查数据库表是否存在，如果不存在，执行sql指令创建表。
	 *  <b style="color:#F00">注意：</b>如果表已经存在，不会检查字段是否正确，不能动态添加表字段 。
	 *  </li>
	 *  </ol>
	 * </ul>
	 * @throws SQLException
	 * @throws IOException
	 */
	@PostConstruct
	public void init() throws SQLException, IOException {

		try {
			String osName = getOSName();
			logger.info("os name:" + osName);
			
			if(!osName.equals("linux")) {
				checkDatabase();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 初始化数据库表
		createMyTables();
	}

	/** 检查数据库目录和文件是否存在，如果不存在，则创建 */
	public Map<String, String> checkDatabase() throws Exception {
		Map<String, String> result = new HashMap<String, String>();
		
		String sqlite = sqliteDbPath.substring(sqliteDbPath.lastIndexOf(":") - 1, sqliteDbPath.length());
		// "D:/sqlite/sqlite.db";
		
		logger.info("\n\nsqlite数据库文件地址1: " + sqlite);
		File audioStationDbFile = new File(sqlite);
		logger.info("\n\nsqlite数据库文件地址2: " + audioStationDbFile.getAbsolutePath());
		logger.info("\n\n");
		if (!audioStationDbFile.getParentFile().exists()) {
			audioStationDbFile.getParentFile().mkdirs();
		}
		if (!audioStationDbFile.exists()) {
			audioStationDbFile.createNewFile();
		}
		return result;

	}

	/**
	 * <h2>创建用户表</h2>
	 * 
	 * @return 创建用户表sql语句
	 */
	private String createAmbariInstallInfoSql() {
		StringBuffer sql = new StringBuffer();
		sql.append("CREATE TABLE 't_ambari_ins_info'(\n ");
		sql.append("'id' integer NOT NULL PRIMARY KEY AUTOINCREMENT,\n");
		sql.append("'ambari_ip' TEXT NOT NULL,\n");
		sql.append("'step_name' TEXT NOT NULL,\n");
		sql.append("'step_status' integer ,\n");
		sql.append("'active' integer \n");
		sql.append(");");
		return sql.toString();

	}

	/**
	 * <h2>创建用户表</h2>
	 * 
	 * @return 创建用户表sql语句
	 */
	private String createUserTableSql() {
		StringBuffer sql = new StringBuffer();
		sql.append("CREATE TABLE 't_user'(\n ");
		sql.append("'id' integer NOT NULL PRIMARY KEY AUTOINCREMENT,\n");
		sql.append("'account' TEXT NOT NULL,\n");
		sql.append("'password' TEXT NOT NULL,\n");
		sql.append("'username' TEXT ,\n");
		sql.append("'user_type' TEXT ,\n");
		sql.append("'address' TEXT \n");
		sql.append(");");
		return sql.toString();

	}

	/**
	 * <h2>创建用户表</h2>
	 * 
	 * @return 创建用户表sql语句
	 */
	private String createHostTableSql() {
		StringBuffer sql = new StringBuffer();
		sql.append("CREATE TABLE 't_server_host'(\n ");
		sql.append("'id' integer NOT NULL PRIMARY KEY AUTOINCREMENT,\n");
		sql.append("'host_ip' TEXT NOT NULL UNIQUE,\n");
		sql.append("'host_name' TEXT ,\n");
		sql.append("'account' TEXT NOT NULL,\n");
		sql.append("'password' TEXT NOT NULL,\n");
		sql.append("'host_port' integer ,\n");
		
		sql.append("'yum_flag' integer ,\n");
		sql.append("'jdk_flag' integer ,\n");
		sql.append("'is_sys_lib_flag' integer ,\n");
		sql.append("'is_ntpd_flag' integer ,\n");
		sql.append("'is_ntpd_client_flag' integer ,\n");
		
		sql.append("'is_hosts_flag' integer ,\n");
		sql.append("'firewall_flag' integer ,\n");
		sql.append("'selinux_flag' integer ,\n");
		sql.append("'ssh_flag' integer ,\n");
		sql.append("'is_optimize' integer ,\n");
		
		sql.append("'is_httpd_flag' integer ,\n");
		sql.append("'is_sql_flag' integer ,\n");
		
		sql.append("'is_ambari_flag' integer, \n");
		sql.append("'is_ambari_client_flag' integer ,\n");
		sql.append("'is_ambari_db_driver_flag' integer ,\n");
		sql.append("'is_ambari_setup_flag' integer ,\n");
		sql.append("'is_ambari_db_init' integer ,\n");
		sql.append("'is_ambari_server_optimize' integer ,\n");
		
		sql.append("'UPDATE_LAST_DATE' text \n");
		sql.append(");");
		return sql.toString();

	}

	/**
	 * <h2>创建应用表</h2>
	 * 
	 * @return 创建用户表sql语句
	 */
	private String createAppTableSql() {
		StringBuffer sql = new StringBuffer();
		sql.append("CREATE TABLE 't_app'(\n ");
		sql.append("'id' integer NOT NULL PRIMARY KEY AUTOINCREMENT,\n");
		sql.append("'app_ip' TEXT NOT NULL,\n");
		sql.append("'app_name' TEXT NOT NULL,\n");
		sql.append("'app_type' TEXT NOT NULL,\n");
		sql.append("'username' TEXT,\n");
		sql.append("'password' TEXT,\n");
		sql.append("'driver' TEXT,\n");
		sql.append("'app_port' integer,\n");
		sql.append("'app_docker_path' TEXT,\n");
		sql.append("'app_flag' TEXT\n");
		sql.append(");");
		return sql.toString();

	}

	/**
	 * 初始化表
	 */
	private void createMyTables() throws SQLException {
		Connection connection = dataSource.getConnection();
		List<Entity> list = SqlExecutor.query(connection, "SELECT name FROM sqlite_master ", new EntityListHandler());
		List<String> tables = list.stream().map(x -> x.get("name").toString()).collect(Collectors.toList());

		if (!tables.contains("t_user")) {
			SqlExecutor.execute(connection, createUserTableSql());
		}
		if (!tables.contains("t_server_host")) {
			SqlExecutor.execute(connection, createHostTableSql());
		}
		if (!tables.contains("t_app")) {
			SqlExecutor.execute(connection, createAppTableSql());
		}
		if (!tables.contains("t_ambari_ins_info")) {
			SqlExecutor.execute(connection, createAmbariInstallInfoSql());
		}

	}
}
